/**
 *	@file	pgmap_key.c
 *	@brief	ポケギアマップ　入力関連関数群
 *	@author	Miyuki Iwasawa
 *	@
 */

#include "common.h"
#include "system/procsys.h"
#include "system/arc_util.h"
#include "system/arc_tool.h"
#include "system/brightness.h"
#include "system/bmp_list.h"
#include "system/bmp_menu.h"
#include "system/pm_str.h"
#include "system/msgdata.h"
#include "system/fontproc.h"
#include "system/snd_tool.h"
#include "system/clact_util.h"
#include "system/clact_tool.h"
#include "system/render_oam.h"
#include "system/wipe.h"
#include "system/buflen.h"
#include "system/palanm.h"
#include "gflib/touchpanel.h"
#include "field/field_matrix.h"
#include "field/field_place_name.h"
#include "application/app_tool.h"
#include "application/pokegear.h"
#include "msgdata/msg.naix"

#include "../pgear_sys.h"
#include "../pgear_frm.h"
#include "../pgear_act.h"
#include "pgmap_sys.h"

#define __BGMAP_KEY_H_GLOBAL
#include "pgmap_key.h"
#include "pgmap_sub.h"
#include "pgmap_mk.h"

///プロトタイプ
static int PGMapKey_TouchContMap(PGMAP_SYS_WORK* wk,BOOL* touch_f);
static void pgmapkey_setAffParam(PGMAP_SYS_WORK* wk,u16 tx,u16 tz,
		int* centerX,int* centerY);
static void pgmapkey_GetTouchGridPos(PGMAP_SYS_WORK* wk,s16* tx,s16* tz);
static int pgmapkey_GetTouchScrolArea(PGMAP_SYS_WORK* wk);

static void pgmapkey_ObjVisibleStateCheck(PGEAR_ACT_WORK* act,u16 idx, s16 py);
//BTS4346 赤い丸野表示の更新を別関数化
static void pgmapkey_UpdateActorDispMark( PGMAP_SYS_WORK* wk );

/**
 *	@brief	マップ画面　キー入力取得
 */
int PGMapKey_InputKey(PGMAP_SYS_WORK* wk)
{
	int ret = PG_NEXT_NULL;

	if((sys.trg & PAD_BUTTON_B) && (!wk->cmove_st)){	//システムキーモードに戻る
		wk->sys->control = PGCONT_SYS;
		CursorMvMan_SetCursorDrawFlag(wk->sys->curMan,0,TRUE);
		CursorMvMan_SetCurrent(wk->sys->curMan,PGKM_SYS_PARAM,PGFrame_GetSCurModePosNo(wk->sys));
		PGMapSub_ToSysKeyChange((void*)wk);

		Snd_SePlay(SE_PGEAR_CANCEL);
		return PG_NEXT_NULL;
	}
	//通常キー操作
	ret = PGMapKey_ContMap(wk);
	if(ret == PG_NEXT_MARK){
		return ret;
	}
	PGMapKey_UpdateCursor(wk);
	PGMapKey_UpdateAffine(wk);
	return PG_NEXT_NULL;
}

/**
 *	@brief	マップ画面　タッチ入力取得
 */
int PGMapKey_InputTouch(PGMAP_SYS_WORK* wk,BOOL* touch_f)
{
	int ret = PG_NEXT_NULL;

	if(wk->touch_st == 0){
		ret = PGFrame_TpControl(wk->sys);
	}
	if(ret != PG_NEXT_NULL){
		*touch_f = TRUE;
		return ret;
	}
	if(wk->touch_st == 0){
		ret = PGMapKey_TouchContMap(wk,touch_f);

		if(*touch_f && (wk->sys->control == PGCONT_SYS)){
			wk->sys->control = PGCONT_APP;
			PGMapSub_ToTouchChangeMap((void*)wk);
		}
		if(ret == PG_NEXT_MARK){
			return ret;
		}
		PGMapKey_UpdateAffine(wk);
	}else{
		*touch_f = TRUE;
		ret = PGMapKey_TouchContMapScrl(wk);
	}
	return ret;
}


/**
 *	@brief	キー入力　十字キー受付
 */
static int pgmapkey_ContMapCross(PGMAP_SYS_WORK* wk)
{
	u8	flag = 0;
	int key_c = sys.cont;
	PGEAR_ACT_WORK* pCur = &wk->pActWMan->pAct[NACT_CURSOR];

	if(key_c & PAD_KEY_UP){
		if(wk->cTarget.z > (wk->scrl.lim_bu+1)){
			wk->cTarget.z -= 1;
			wk->key_dir |= KEYDIR_FU;
			flag = 1;
		}
	}else if(key_c & PAD_KEY_DOWN){
		if(wk->cTarget.z < (wk->scrl.lim_bd)){
			wk->cTarget.z += 1;
			wk->key_dir |= KEYDIR_FD;
			flag = 1;
		}
	}
	if(key_c & PAD_KEY_LEFT){
		if(wk->cTarget.x > (wk->scrl.lim_bl+1)){
			wk->cTarget.x -= 1;
			wk->key_dir |= KEYDIR_FL;
			flag = 1;
		}
	}else if(key_c & PAD_KEY_RIGHT){
		if(wk->cTarget.x < (wk->scrl.lim_br-1)){
			wk->cTarget.x += 1;
			wk->key_dir |= KEYDIR_FR;
			flag = 1;
		}
	}
	if(flag){
		wk->key_move = KEYMOVE_CT;
		wk->input_st = TRUE;
		wk->cmove_st = TRUE;
		//動く前のカーソル座標を覚えておく
		wk->o_cursor = pCur->pos;

//		Snd_SePlay(SE_PGEAR_MOVE_CURSOR);
		IWASAWA_PRINT("#KeyIn : %d:%d\n",wk->cTarget.x,wk->cTarget.z);
		return 1;
	}
	return 0;
}

static int pgmapkey_SetSkyJumpParam(PGMAP_SYS_WORK* wk,int zone)
{
	u16 lineX,lineY;

	if(zone < 0){
		return PG_NEXT_NULL;
	}
	wk->sys->next_mode = PG_NEXT_JUMP;
	wk->sys->param->ret_zone = zone;
	wk->sys->param->ret_x = wk->cTarget.x;
	wk->sys->param->ret_z = wk->cTarget.z-PGMAP_MATOFS_Z;

	//座標でライン判定
	if(wk->sys->key_mode == APP_KTST_TOUCH){
		PGMapSub_GetPosLine(wk,sys.tp_x,sys.tp_y,&lineX,&lineY);
	}else{
		PGMapSub_GetPosLine(wk,
				wk->pActWMan->pAct[NACT_CURSOR].pos.x,
				wk->pActWMan->pAct[NACT_CURSOR].pos.y,
				&lineX,&lineY);
	}
	PGMapSub_PrintExpMsg(wk,wk->cZone.z_prm->zone_id);

#ifdef PM_DEBUG
	if(wk->debug_f){
		wk->sys->param->retval = 1;
		return PG_NEXT_EXIT;
	}else{
		PGMapSub_SkySelBoxSet(wk,lineX);
		return PG_NEXT_APP_SEQ;
	}
#else
	PGMapSub_SkySelBoxSet(wk,lineX);
	return PG_NEXT_APP_SEQ;
#endif
}

/**
 *	@brief	キー入力　マップカーソル移動入力検知
 */
int PGMapKey_ContMap(PGMAP_SYS_WORK* wk)
{
	u8	flag = 0;
	int key_t = sys.trg;
	int key_c = sys.cont;

	if(key_c == 0 || wk->input_st || wk->aff_st || wk->cmove_st){
		return PG_NEXT_NULL;
	}

	//拡縮
	if(key_t & PAD_BUTTON_X){
		wk->f_affine ^= 1;	//モード切替
		wk->key_move = AFFMOVE_CT;

		//拡縮中心座標を取得
		pgmapkey_setAffParam(wk,
			wk->cTarget.x,wk->cTarget.z,
			&wk->cScrl.cx,&wk->cScrl.cy);

		wk->input_st = 1;
		wk->aff_st = 1;

		PGMapSub_MapPanelStChange(wk,1,wk->f_affine);
		if(wk->f_affine == 1){
			Snd_SePlay(SE_PGEAR_MAP_X_UP);
		}else{
			Snd_SePlay(SE_PGEAR_MAP_X_DOWN);
		}
		IWASAWA_PRINT("#AffineIn : %d:%d\n",wk->cTarget.x,wk->cTarget.z);
		return PG_NEXT_NULL;
	}else if(key_t & PAD_BUTTON_Y){
		if(!PGMapSub_IsMarkingEnable(wk,&wk->cZone)){
			return PG_NEXT_NULL;
		}
		//マーキング画面へ移行
		PGMapSub_MapPanelStChange(wk,0,1);
		Snd_SePlay(SE_PGEAR_DECIDE);

		IWASAWA_PRINT("#MarkIn : %d:%d\n",wk->cTarget.x,wk->cTarget.z);
		return PG_NEXT_MARK;
	}
	if(pgmapkey_ContMapCross(wk)){
		//ガイド表示更新
		PGMapSub_GetNowZone(wk,&(wk->cZone),wk->cTarget.x,wk->cTarget.z);
		PGMapSub_DrawGuide(wk,FALSE);
		//ハイライト更新
		PGMapSub_DrawTargetZoneHilight(wk,TRUE);
	}
	return PG_NEXT_NULL;
}

/**
 *	@brief	空を飛ぶ画面キー入力　マップカーソル移動入力検知
 */
int PGSkyKey_ContMap(PGMAP_SYS_WORK* wk)
{
	u8	flag = 0;
	int zone,ret;
	int key_t = sys.trg;
	int key_c = sys.cont;

	ret = PG_NEXT_NULL;

	if(key_c == 0 || wk->input_st || wk->cmove_st){
		return PG_NEXT_NULL;
	}

	//空を飛ぶ
	if(key_t & PAD_BUTTON_A && wk->map_mode == MAP_MODE_JUMP){
		//現在選択されているゾーンが空を飛ぶの対象か？
		zone = PGMapSub_JumpTargetCheck(wk,wk->cTarget.x,wk->cTarget.z-PGMAP_MATOFS_Z);
		if(zone > 0){
			Snd_SePlay(SE_PGEAR_DECIDE);
			return pgmapkey_SetSkyJumpParam(wk,zone);
		}
		return PG_NEXT_NULL;
	}else if(key_t & PAD_BUTTON_B){
		Snd_SePlay(SE_PGEAR_CANCEL);
		return PG_NEXT_EXIT;
	}
	ret = pgmapkey_ContMapCross(wk);
	if(!ret){
		return PG_NEXT_NULL;
	}
	if(wk->map_mode == MAP_MODE_BG){
		PGMapSub_GetNowZone(wk,&(wk->cZone),wk->cTarget.x,wk->cTarget.z);

		//ガイド表示更新
		PGMapSub_DrawGuide(wk,TRUE);
		PGMapSub_DrawTargetZoneHilight(wk,TRUE);
	}else{
#ifdef PM_DEBUG
		if(wk->debug_f){
			PGMapSub_GetNowZone(wk,&(wk->cZone),wk->cTarget.x,wk->cTarget.z);
		}else{
			PGMapSub_GetNowZoneSky(wk,&(wk->cZone),wk->cTarget.x,wk->cTarget.z);
		}
#else
		PGMapSub_GetNowZoneSky(wk,&(wk->cZone),wk->cTarget.x,wk->cTarget.z);
#endif
		//ガイド表示更新
		PGMapSub_DrawGuide(wk,FALSE);
		PGMapSub_DrawTargetZoneHilight(wk,TRUE);
	}
	return PG_NEXT_NULL;
}

/**
 *
 */
static const RECT_HIT_TBL MapField_TpRect[2] = {
	{TPMAP_MAP_PY,TPMAP_MAP_PY+TPMAP_MAP_SY,TPMAP_MAP_PX,TPMAP_MAP_PX+TPMAP_MAP_SX},
	{TPSKY_MAP_PY,TPSKY_MAP_PY+TPSKY_MAP_SY,TPSKY_MAP_PX,TPSKY_MAP_PX+TPSKY_MAP_SX},
};

/**
 *	@brief	タッチパネルマップ操作
 */
static int PGMapKey_TouchContMap(PGMAP_SYS_WORK* wk,BOOL* touch_f)
{
	int ret = PG_NEXT_NULL;
	u16	lx,lz;
	static const RECT_HIT_TBL Btn_TpRect[] = {
//		{0,191,0,255}, ty,by,lx,rx
		{TPMAP_MARK_PY,TPMAP_MARK_PY+TPMAP_MARK_SY,TPMAP_MARK_PX,TPMAP_MARK_PX+TPMAP_MARK_SX},
		{TPMAP_AFF_PY,TPMAP_AFF_PY+TPMAP_AFF_SY,TPMAP_AFF_PX,TPMAP_AFF_PX+TPMAP_AFF_SX},
		{RECT_HIT_END,0,0,0}
	};

	if(GF_TP_GetCont() == 0){
		return PG_NEXT_NULL;
	}
	if(wk->input_st || wk->aff_st){
		return PG_NEXT_NULL;
	}

	ret = GF_TP_RectHitTrg(Btn_TpRect);
	if(	ret != RECT_HIT_NONE )
	{
		*touch_f = TRUE;

		//カーソル位置を更新しておく
		PGMapSub_SetCursor2TargetPos(wk);

		if(ret == 0){
			if(!PGMapSub_IsMarkingEnable(wk,&wk->cZone)){
				return PG_NEXT_NULL;
			}
			//マーキング画面へ移行
			PGMapSub_MapPanelStChange(wk,0,1);
			Snd_SePlay(SE_PGEAR_DECIDE);
			IWASAWA_PRINT("#MarkIn : %d:%d\n",wk->cTarget.x,wk->cTarget.z);
			return PG_NEXT_MARK;
		}else{
			wk->f_affine ^= 1;	//モード切替
			wk->key_move = AFFMOVE_CT;

			//拡縮中心座標を取得
			pgmapkey_setAffParam(wk,
				wk->cTarget.x,wk->cTarget.z,
				&wk->cScrl.cx,&wk->cScrl.cy);

			wk->input_st = 1;
			wk->aff_st = 1;
			PGMapSub_MapPanelStChange(wk,1,wk->f_affine);
			if(wk->f_affine == 1){
				Snd_SePlay(SE_PGEAR_MAP_X_UP);
			}else{
				Snd_SePlay(SE_PGEAR_MAP_X_DOWN);
			}
			IWASAWA_PRINT("#AffineIn : %d:%d\n",wk->cTarget.x,wk->cTarget.z);
		}
		return PG_NEXT_NULL;
	}
	if(GF_TP_SingleHitTrg(&MapField_TpRect[0]) == FALSE){
		return PG_NEXT_NULL;
	}
	{
		u16 pat = 0x0001;	//1111 1111 1111 1110	無効パレットbit(onになっている色Noのみ反応させる)
  	if(	GF_BGL_DotCheck(wk->sys->bgl,GF_BGL_FRAME1_M,sys.tp_x,sys.tp_y,&pat) == FALSE){
  		return PG_NEXT_NULL;
  	}
  }

	Snd_SePlay(SE_PGEAR_MAP_TOUCH);
	//現在のグリッド座標を取得
	pgmapkey_GetTouchGridPos(wk,&(wk->cTarget.x),&(wk->cTarget.z));

	//ガイド表示更新
	PGMapSub_GetNowZone(wk,&(wk->cZone),wk->cTarget.x,wk->cTarget.z);
	PGMapSub_DrawGuide(wk,FALSE);
	//ハイライト更新
	PGMapSub_DrawTargetZoneHilight(wk,TRUE);

	//現在のタッチ座標を取得
	wk->tp_sx = wk->tp_ox = sys.tp_x;
	wk->tp_sy = wk->tp_oy = sys.tp_y;

	IWASAWA_PRINT(" ->Map Scroll In ...\n");
	pgmapkey_GetTouchScrolArea(wk);

	wk->touch_st = 1;
	*touch_f = TRUE;
	return PG_NEXT_NULL;
}

/**
 *	@brief	空を飛ぶ タッチパネルマップ操作
 */
int PGSkyKey_TouchContMap(PGMAP_SYS_WORK* wk,int* touch_f)
{
	int ret,zone;
	u16	pat;
	u16	lx,lz;
	static const RECT_HIT_TBL Btn_TpRect[] = {
//		{0,191,0,255}, ty,by,lx,rx
		{TPSKY_EXIT_PY,TPSKY_EXIT_PY+TPSKY_EXIT_SY,TPSKY_EXIT_PX,TPSKY_EXIT_PX+TPSKY_EXIT_SX},
		{RECT_HIT_END,0,0,0}
	};

	if(GF_TP_GetCont() == 0){
		return PG_NEXT_NULL;
	}
	if(wk->input_st){
		return PG_NEXT_NULL;
	}

	ret = GF_TP_RectHitTrg(Btn_TpRect);
	if(	ret != RECT_HIT_NONE ){
		//フレーム書き込み
		GF_BGL_ScrWriteExpand(wk->sys->bgl,GF_BGL_FRAME1_M,
			24,20,8,4,wk->pSFrm->rawData,0,24,
			wk->pSFrm->screenWidth/8,wk->pSFrm->screenHeight/8);
		GF_BGL_LoadScreenV_Req(wk->sys->bgl,GF_BGL_FRAME1_M);

		//カーソル位置を更新しておく
		PGMapSub_SetCursor2TargetPos(wk);
		Snd_SePlay(SE_PGEAR_CANCEL);
		*touch_f = TRUE;
		return PG_NEXT_EXIT;
	}
	if(GF_TP_SingleHitTrg(&MapField_TpRect[1]) == FALSE){
		return PG_NEXT_NULL;
	}
	pat = 0x0001;	//1111 1111 1111 1110	無効パレットbit(onになっている色Noのみ反応させる)
	if(	GF_BGL_DotCheck(wk->sys->bgl,GF_BGL_FRAME1_M,sys.tp_x,sys.tp_y,&pat) == FALSE){
		return PG_NEXT_NULL;
	}
	Snd_SePlay(SE_PGEAR_MAP_TOUCH);
	*touch_f = TRUE;

	if(wk->map_mode == MAP_MODE_BG){
		//現在のグリッド座標を取得
		pgmapkey_GetTouchGridPos(wk,&(wk->cTarget.x),&(wk->cTarget.z));

		//ガイド表示更新
		PGMapSub_GetNowZone(wk,&(wk->cZone),wk->cTarget.x,wk->cTarget.z);
		PGMapSub_DrawGuide(wk,TRUE);
		//ハイライト更新
		PGMapSub_DrawTargetZoneHilight(wk,TRUE);
	}else{
#ifdef PM_DEBUG
		//現在のグリッド座標を取得
		pgmapkey_GetTouchGridPos(wk,&(wk->cTarget.x),&(wk->cTarget.z));
		if(wk->debug_f){
			PGMapSub_GetNowZone(wk,&(wk->cZone),wk->cTarget.x,wk->cTarget.z);
		}else{
			PGMapSub_GetNowZoneSky(wk,&(wk->cZone),wk->cTarget.x,wk->cTarget.z);
		}
#else
		//現在のグリッド座標を取得
		pgmapkey_GetTouchGridPos(wk,&(wk->cTarget.x),&(wk->cTarget.z));
		PGMapSub_GetNowZoneSky(wk,&(wk->cZone),wk->cTarget.x,wk->cTarget.z);
#endif	//PM_DEBUG
		//ガイド表示更新
		PGMapSub_DrawGuide(wk,FALSE);
		//ハイライト更新
		PGMapSub_DrawTargetZoneHilight(wk,TRUE);

		//現在選択されているゾーンが空を飛ぶの対象か？
		zone = PGMapSub_JumpTargetCheck(wk,wk->cTarget.x,wk->cTarget.z-PGMAP_MATOFS_Z);
		if(zone > 0){
			Snd_SePlay(SE_PGEAR_DECIDE);
			return pgmapkey_SetSkyJumpParam(wk,zone);
		}
	}

	//現在のタッチ座標を取得
	wk->tp_sx = wk->tp_ox = sys.tp_x;
	wk->tp_sy = wk->tp_oy = sys.tp_y;

	IWASAWA_PRINT(" ->Map Scroll In ...\n");
	pgmapkey_GetTouchScrolArea(wk);

	wk->touch_st = 1;
	return PG_NEXT_NULL;
}

/**
 *
 */
static int pgmapkey_GetTouchScrolArea(PGMAP_SYS_WORK* wk)
{
	s16	x,y,lx,lz,ox,oy;
	u8	grid,grid_h;
	u8	gsiz_w,gsiz_h;
	s16	lim_u,lim_d,lim_r,lim_l;
	s16	d_u,d_d,d_r,d_l;

	//グリッド幅を取得
	if(wk->f_affine){
		gsiz_w = MAPF_GAFF1_W;
		gsiz_h = MAPF_GAFF1_H;
	}else{
		gsiz_w = MAPF_GAFF0_W;
		gsiz_h = MAPF_GAFF0_H;
	}
	grid = (MAPF_GRID_SIZ * (1+wk->f_affine));
	grid_h = grid/2;

	//オフセットを除いた座標を取得
	x = sys.tp_x - wk->mapf_lsiz;
	y = sys.tp_y - wk->mapf_usiz;

	//今タッチしたグリッドとその中心座標からのオフセットを取得
	ox = (x % grid) - grid_h;
	oy = (y % grid) - grid_h;

	//ライン座標に変換
	lx = x / grid;
	lz = y / grid;

	//タッチエリア内スクロールのリミットを取得
	lim_u = wk->cTarget.z - lz;
	lim_d = wk->cTarget.z + (gsiz_h-1-lz);
	lim_l = wk->cTarget.x - lx;
	lim_r = wk->cTarget.x + (gsiz_w-1-lx);

	//スクロールリミットで補正
	if(lim_u < wk->scrl.lim_bu){
		lim_u = wk->scrl.lim_bu;
	}
	if(lim_l < wk->scrl.lim_bl){
		lim_l = wk->scrl.lim_bl;
	}
	if(lim_d > wk->scrl.lim_bd){
		lim_d = wk->scrl.lim_bd;
	}
	if(lim_r > wk->scrl.lim_br){
		lim_r = wk->scrl.lim_br;
	}

	//実際に動かせる範囲
	d_u = (wk->cTarget.z-lim_u)*grid+oy;
	d_l = (wk->cTarget.x-lim_l)*grid+ox;
	d_d = (lim_d-wk->cTarget.z)*grid+oy;
	d_r = (lim_r-wk->cTarget.x)*grid+ox;

	wk->tp_lu = d_u;
	wk->tp_ld = d_d;
	wk->tp_ll = d_l;
	wk->tp_lr = d_r;

	IWASAWA_PRINT(" ScrlLimit00 up=%d,down=%d,left=%d.right=%d\n",d_u,d_d,d_l,d_r);
	IWASAWA_PRINT(" ScrlLimit01 up=%d,down=%d,left=%d.right=%d\n",lim_u,lim_d,lim_l,lim_r);
	return 0;
}

/**
 *	@brief	ターゲットスクロールアウト防止補正　横軸方向
 */
static s16 pgmapkey_soutCheckDx(PGMAP_SYS_WORK* wk,s16 dx)
{
	s16	dif,lim_l,lim_r;

	//スクロールの結果見える範囲を特定
	lim_l = wk->cScrl.b_l-dx+1;
	lim_r = wk->cScrl.b_r-dx-1;

	if(wk->cTarget.x >= lim_l && lim_r >= wk->cTarget.x){
		return dx;
	}
	//ターゲットがスクロールアウトしないかチェック
	if(wk->cTarget.x <= lim_l){
		dif = dx+(lim_l-wk->cTarget.x);
	}else if(wk->cTarget.x >= lim_r){
		dif = dx-(wk->cTarget.x-lim_r);
	}
	IWASAWA_PRINT(" soutCheck tx = %d, lim_l = %d, lim_r = %d, dx = %d, dif = %d\n",
			wk->cTarget.x,lim_l,lim_r,dx,dif);
	return dif;
}

/**
 *	@brief	横軸方向のスクロール許容値を返す
 */
static s16	pgmapkey_getScrollDX(PGMAP_SYS_WORK* wk,s16 dx,s16 ax)
{
	s16	rx,tx,lim_l,lim_r;

	if(dx > 0){	//to right
		tx = wk->cScrl.b_l - wk->scrl.lim_bl;
		if(tx <= 0){
			return 0;
		}
		if(tx < ax){
			tx = pgmapkey_soutCheckDx(wk,tx);
			return tx;
		}
	}else{	//to left
		tx = wk->scrl.lim_br-wk->cScrl.b_r;
		if(tx <= 0){
			return 0;
		}
		if(tx < ax){
			tx = pgmapkey_soutCheckDx(wk,-tx);
			return tx;
		}
	}
	dx = pgmapkey_soutCheckDx(wk,dx);
	return dx;
}

/**
 *	@brief	ターゲットスクロールアウト防止補正　縦軸方向
 */
static s16 pgmapkey_soutCheckDy(PGMAP_SYS_WORK* wk,s16 dy)
{
	s16	dif,lim_u,lim_d;

	//スクロールの結果見える範囲を特定
	lim_u = wk->cScrl.b_u-dy+1;
	lim_d = wk->cScrl.b_d-dy;

	if(wk->cTarget.z >= lim_u && lim_d >= wk->cTarget.z){
		return dy;
	}
	//ターゲットがスクロールアウトしないかチェック
	if(wk->cTarget.z <= lim_u){
		dif = dy + (lim_u-wk->cTarget.z);
	}else if(wk->cTarget.z >= lim_d){
		dif = dy - (wk->cTarget.z-lim_d);
	}
	IWASAWA_PRINT(" soutCheck tz = %d, lim_u = %d, lim_d = %d, dy = %d, dif = %d\n",
			wk->cTarget.z,lim_u,lim_d,dy,dif);
	return dif;
}
/**
 *	@brief	縦軸方向のスクロール許容値を返す
 */
static s16	pgmapkey_getScrollDY(PGMAP_SYS_WORK* wk,s16 dy,s16 ay)
{
	s16	ry,ty;

	if(dy > 0){	//to down
		ty = wk->cScrl.b_u - wk->scrl.lim_bu;
		if(ty <= 0){
			return 0;
		}
		if(ty < ay){
			ty = pgmapkey_soutCheckDy(wk,ty);
			return ty;
		}
	}else{	//to up
		ty = wk->scrl.lim_bd-wk->cScrl.b_d;
		if(ty <= 0){
			return 0;
		}
		if(ty < ay){
			ty = pgmapkey_soutCheckDy(wk,-ty);
			return ty;
		}
	}
	ty = pgmapkey_soutCheckDy(wk,dy);
	return ty;
}

/**
 *	@brief	タッチパネルマップ操作 ドラッグ中
 */
int PGMapKey_TouchContMapScrl(PGMAP_SYS_WORK* wk)
{
	s16 x,y,dx,dy,ax,ay,ox,oy;
	s16	grid,csiz;

	x = sys.tp_x;
	y = sys.tp_y;

	csiz = (MAPF_GRID_SIZ + (MAPF_GRID_SIZ*wk->f_affine))/2;
	if(wk->f_affine){
		grid = 9;
	}else{
		grid = 5;
	}

	if(wk->key_move){
		wk->cScrl.x -= wk->tp_ofsx;
		wk->cScrl.y -= wk->tp_ofsy;
		PGMapSub_MapObjScrollSet(wk,wk->tp_ofsx,wk->tp_ofsy);
		PGActWorkMan_AllPosUpdate(wk->pActWMan);
		wk->f_scrl_up = 1;
		wk->key_move = 0;
		return PG_NEXT_NULL;
	}
	if(GF_TP_GetCont() == FALSE){	//離された

		wk->touch_st = 0;
		IWASAWA_PRINT(" ... Map Scroll Out ->\n");
		return PG_NEXT_NULL;
	}
	dx = ax = (x-wk->tp_ox);
	dy = ay = (y-wk->tp_oy);
	if(ax < 0){
		ax *= -1;
	}
	if(ay < 0){
		ay *= -1;
	}
	ax /= grid;
	ay /= grid;
	ox = dx % grid;
	oy = dy % grid;
	if(ax < 1 && ay < 1){
		return PG_NEXT_NULL;
	}
	wk->tp_ofsx = wk->tp_ofsy = 0;

//	IWASAWA_PRINT( "scrl .. dx=%d,dy=%d  %d,%d \n",dx,dy,(dx/grid),(dy/grid));
	if(ax > 0){
		dx = pgmapkey_getScrollDX(wk,(dx/grid),ax);
		if(dx != 0){
			wk->cScrl.x -= (dx*csiz);
			wk->cScrl.b_r -= dx;
			wk->cScrl.b_l -= dx;
			wk->tp_ox = x-ox;
			wk->key_move = 1;
			wk->tp_ofsx = (dx*csiz);
			IWASAWA_PRINT(" scrl x = %d, lim_l = %d ,lim_r = %d\n",dx,wk->cScrl.b_l,wk->cScrl.b_r);
		}
	}else{
		dx = 0;
	}
	if(ay > 0){
		dy = pgmapkey_getScrollDY(wk,(dy/grid),ay);
		if(dy != 0){
			wk->cScrl.y -= (dy*csiz);
			wk->cScrl.b_d -= dy;
			wk->cScrl.b_u -= dy;
			wk->tp_oy = y-oy;

			wk->key_move = 1;
			wk->tp_ofsy = (dy*csiz);
			IWASAWA_PRINT(" scrl y = %d, lim_u = %d ,lim_d = %d\n",dy,wk->cScrl.b_u,wk->cScrl.b_d);
		}
	}else{
		dy = 0;
	}
//	IWASAWA_PRINT( " ..\n");

	//マップ連動オブジェクトスクロール
	if(dx != 0 || dy != 0){
		PGMapSub_MapObjScrollSet(wk,dx*csiz,dy*csiz);
		//BTS4346 赤い丸野表示の更新
		pgmapkey_UpdateActorDispMark( wk );
		PGActWorkMan_AllPosUpdate(wk->pActWMan);
		wk->f_scrl_up = 1;
	}
	return PG_NEXT_NULL;
}

/**
 *	@brief	キー入力　マップカーソル移動処理
 */
void PGMapKey_UpdateCursor(PGMAP_SYS_WORK* wk)
{
	u8	s_flag = 0;
	s16	dx = 0,dy = 0,diff = 0;
	u16	lineX,lineY;
	PGEAR_ACT_WORK* pCur = &wk->pActWMan->pAct[NACT_CURSOR];

	static const u8 scrlLim[][2] = {
	 {MAPF_GAFF0_W-2,MAPF_GAFF1_W-2},{MAPF_GAFF0_H-1,MAPF_GAFF1_H-1}
	};
	if(wk->cmove_st == FALSE){
		return;
	}
	if(wk->f_affine){
		diff = KEYMOVE_OFS*2;
	}else{
		diff = KEYMOVE_OFS;
	}
	//動く前の座標でライン判定
	PGMapSub_GetPosLine(wk,wk->o_cursor.x,wk->o_cursor.y,&lineX,&lineY);

	if(wk->key_dir & KEYDIR_FU){
		if(lineY <= 1){
			dy -= diff;
			s_flag = 1;
		}else{
			pCur->pos.y -= diff;
		}
	}else if(wk->key_dir & KEYDIR_FD){
		if(lineY >= scrlLim[1][wk->f_affine]){
			dy += diff;
			s_flag = 1;
		}else{
			pCur->pos.y += diff;
		}
	}
	if(wk->key_dir & KEYDIR_FL){
		if(lineX <= 1){
			dx -= diff;
			s_flag = 1;
		}else{
			pCur->pos.x -= diff;
		}
	}else if(wk->key_dir & KEYDIR_FR){
		if(lineX >= scrlLim[0][wk->f_affine]){
			dx += diff;
			s_flag = 1;
		}else{
			pCur->pos.x += diff;
		}
	}

	//スクロール位置更新
	if(s_flag){
		wk->f_scrl_up = 1;
		wk->cScrl.x += dx;
		wk->cScrl.y += dy;

		//Snd_SePlay(SE_PGEAR_MOVE_CURSOR);
		//マップ連動オブジェクトスクロール
		PGMapSub_MapObjScrollSet(wk,-dx,-dy);
		//BTS4346  赤い丸野表示の更新
		pgmapkey_UpdateActorDispMark( wk );
	}
	//オブジェクト位置アップデート
	PGActWorkMan_AllPosUpdate(wk->pActWMan);

	if(--wk->key_move == 0){
		PGMapSub_SetViewAreaFromScroll(wk);
		wk->input_st = FALSE;
		wk->cmove_st = FALSE;
		wk->key_dir = 0;
	}
}

/**
 *	@brief	拡縮実行パラメータをセット
 */
static void pgmapkey_setAffParam(PGMAP_SYS_WORK* wk,u16 tx,u16 tz,
		int* centerX,int* centerY)
{
	u16	i;
	u16	lineX,lineY;
	s16	dx,dy,sx,sy;
	u8	typeX = 0,typeY = 0,grid,grid_h;
	PGEAR_ACT_WORK* pCur = &wk->pActWMan->pAct[NACT_CURSOR];
	PGEAR_ACT_WORK* pAct = wk->pActWMan->pAct;

	grid = MAPF_GRID_SIZ * (wk->f_affine+1);
	grid_h = grid/2;

	IWASAWA_PRINT(" #Cursor= %d,%d\n",pCur->pos.x,pCur->pos.y);
	//BGスクロール移動先座標の取得
	PGMapSub_GetAffMovePos(wk,wk->f_affine,wk->cTarget.x,wk->cTarget.z,pCur->pos.x,pCur->pos.y);

	//拡大→ノーマル
	if(wk->f_affine == 0){
		//拡縮中心座標を取得
		typeX = ((pCur->pos.x-wk->mapf_lsiz)/(MAPF_GRID_SIZ*2));
		typeY = ((pCur->pos.y-wk->mapf_usiz)/(MAPF_GRID_SIZ*2));
//		typeX = ((pCur->pos.x-16)/(MAPF_GRID_SIZ*2));
//		typeY = ((pCur->pos.y-16)/(MAPF_GRID_SIZ*2));
		if(typeX <= MAPF_GAFF1_CX){
			*centerX = tx*MAPF_GRID_SIZ+MAPF_GRID_SIZ;
		}else{
			*centerX = tx*MAPF_GRID_SIZ;
		}
		if(typeY > MAPF_GAFF1_CY){
			*centerY = tz*MAPF_GRID_SIZ+MAPF_GRID_SIZ;
		}else{
			*centerY = tz*MAPF_GRID_SIZ;
		}

	}else{	//ノーマル→拡大
		typeX = ((pCur->pos.x-wk->mapf_lsiz)/MAPF_GRID_SIZ)%2;
		typeY = ((pCur->pos.y-wk->mapf_usiz)/MAPF_GRID_SIZ)%2;
//		typeX = ((pCur->pos.x-16)/MAPF_GRID_SIZ)%2;
//		typeY = ((pCur->pos.y-16)/MAPF_GRID_SIZ)%2;

		//拡縮センター座標取得
		*centerX = tx*MAPF_GRID_SIZ+typeX*MAPF_GRID_SIZ;
		*centerY = tz*MAPF_GRID_SIZ+typeY*MAPF_GRID_SIZ;
	}
	//スクロールの到達座標からオブジェの移動先座標を取得
	pCur->ex = ((tx-wk->cScrl.b_l))*grid+wk->mapf_lsiz+grid_h;
	pCur->ey = ((tz-wk->cScrl.b_u))*grid+wk->mapf_usiz+grid_h;
	pAct[NACT_HERO].ex = (pAct[NACT_HERO].gx-wk->cScrl.b_l)*grid+wk->mapf_lsiz+grid_h;
	pAct[NACT_HERO].ey = (pAct[NACT_HERO].gz-wk->cScrl.b_u)*grid+wk->mapf_usiz+grid_h;
	PGMapSub_MarkPosViewSet(wk,1);

	//移動差分を計算しておく
	for(i = NACT_CURSOR;i < wk->pActWMan->actNum;i++){
		pAct[i].dx = FX_Div(FX32_CONST(pAct[i].ex-pAct[i].pos.x),FX32_CONST(wk->key_move));
		pAct[i].dy = FX_Div(FX32_CONST(pAct[i].ey-pAct[i].pos.y),FX32_CONST(wk->key_move));
		PGActWork_PosSetEx(&pAct[i],pAct[i].pos.x,pAct[i].pos.y);
	}
	IWASAWA_PRINT("#AffCenterType : %d,%d\n",typeX,typeY);
}

/**
 *	@brief	拡縮　移動処理
 */
void PGMapKey_UpdateAffine(PGMAP_SYS_WORK* wk)
{
	u16	i;
	u16 dx,dy;
	fx32	tmpX,tmpY;
	VecFx32	scale;
	PGEAR_ACT_WORK* pCur = &wk->pActWMan->pAct[NACT_CURSOR];
	PGEAR_ACT_WORK* pAct = wk->pActWMan->pAct;

	if(wk->aff_st == 0){
		return;
	}


	//拡縮値更新
	if(wk->f_affine){	//2倍
		wk->cScrl.ax += AFFMOVE_OFS;
		wk->cScrl.ay += AFFMOVE_OFS;
	}else{	//1倍
		wk->cScrl.ax -= AFFMOVE_OFS;
		wk->cScrl.ay -= AFFMOVE_OFS;
	}

	//カーソルスケール更新
	scale.x = wk->cScrl.ax;
	scale.z = FX32_CONST(1);
	scale.y = wk->cScrl.ay;
	CLACT_SetScale(pCur->act, &scale);


	if(--wk->key_move == 0){
		//スクロール最終座標への到達
		wk->cScrl.x = wk->cScrl.bg_end.x;
		wk->cScrl.y = wk->cScrl.bg_end.y;

		for(i = NACT_CURSOR;i < wk->pActWMan->actNum;i++){
			PGActWork_PosSet(&pAct[i],pAct[i].ex,pAct[i].ey);
			pgmapkey_ObjVisibleStateCheck(&pAct[i],i, pAct[i].ey);
		}

		wk->input_st = 0;
		wk->aff_st = 0;
		wk->key_dir = 0;
	}else{
		s16 x,y;
		//拡縮にともなうスクロール値更新
		wk->cScrl.px += wk->cScrl.dx;
		wk->cScrl.py += wk->cScrl.dy;
		wk->cScrl.x = FX_Whole(wk->cScrl.px);
		wk->cScrl.y = FX_Whole(wk->cScrl.py);

		//アクターのスクロール
		for(i = NACT_CURSOR;i < wk->pActWMan->actNum;i++){
			pAct[i].x += pAct[i].dx;
			pAct[i].y += pAct[i].dy;
			x = FX_Whole(pAct[i].x);
			y = FX_Whole(pAct[i].y);
			PGActWork_PosSet(&pAct[i],x,y);
			pgmapkey_ObjVisibleStateCheck(&pAct[i],i,y);
		}
	}
	PGActWorkMan_AllPosUpdate(wk->pActWMan);

	//スクロール状態更新フラグOn
	wk->f_scrl_up = 1;
}

/**
 *	@brief	マップ内OBJの可視範囲チェック
 */
static void pgmapkey_ObjVisibleStateCheck(PGEAR_ACT_WORK* act,u16 idx, s16 py)
{
	if(!act->view_f){
		return;
	}
	if(py > 216 || py < 0){
		IWASAWA_PRINT("Affine Vanish %d y = %d\n",idx,py);
		CLACT_SetDrawFlag(act->act,FALSE);
	}else{
		IWASAWA_PRINT("Affine VanishOff %d y = %d\n",idx,py);
		CLACT_SetDrawFlag(act->act,TRUE);
	}
}

//BTS4346赤い丸野表示の更新を別関数化
/*
 *	@brief	アクターの更新
 */
static void pgmapkey_UpdateActorDispMark( PGMAP_SYS_WORK* wk )
{
	u16	i;
	PGEAR_ACT_WORK* pAct = wk->pActWMan->pAct;
	if( wk->map_mode == MAP_MODE_PG )
	{
		//アクターのスクロール
#if GS_AFTERMASTER_GF1066_20091013_FIX
	  for(i = NACT_CURSOR;i < wk->pActWMan->actNum;i++){
#else
		for(i = MKACT_START;i < MKACT_MAX;i++){
#endif
			pgmapkey_ObjVisibleStateCheck(&pAct[i],i, pAct[i].pos.y);
		}
	}

}


/*
 *	@brief	タッチした座標のグリッド座標を返す
 */
static void pgmapkey_GetTouchGridPos(PGMAP_SYS_WORK* wk,s16* tx,s16* tz)
{
	s16	x,z;
	static const u8 lim_tbl[2][4] = {
	 { 1,16,1,22},	//u,d,l,r
	 { 1,7,1,10 },
	};
	const u8* p_lim = &lim_tbl[wk->f_affine][0];

	//オフセットを除いた座標を取得
	x = sys.tp_x - wk->mapf_lsiz;
	z = sys.tp_y - wk->mapf_usiz;

  //グリッド座標に変換
	x /= (MAPF_GRID_SIZ * (1+wk->f_affine));
	z /= (MAPF_GRID_SIZ * (1+wk->f_affine));
	IWASAWA_PRINT("TouchLine Before= %d:%d\n",x,z);

	//リミットでライン補正
	if(z < p_lim[0]){
		z = p_lim[0];
	}
	if(z > p_lim[1]){
		z = p_lim[1];
	}
	if(x < p_lim[2]){
		x = p_lim[2];
	}
	if(x > p_lim[3]){
		x = p_lim[3];
	}
	IWASAWA_PRINT("TouchLine After= %d:%d\n",x,z);
	x += wk->cScrl.b_l;
	z += wk->cScrl.b_u;

	IWASAWA_PRINT("Touch : %d : %d \n",x,z);

	if(tx != NULL){
		*tx = x;
	}
	if(tz != NULL){
		*tz = z;
	}
	PGMapSub_SetCursor2TargetPos(wk);
}

/**
 *	@brief	タッチした空を飛ぶターゲット候補の情報を返す
 */
static int pgmapkey_GetJumpTargetPos(PGMAP_SYS_WORK* wk,s16* tx,s16 *tz)
{
	int i;
	s16	x,z;
	TMAP_TOWN_PARAM* tp;
	TP_HIT_TBL	tbl;

	//オフセットを除いた座標を取得
	x = sys.tp_x - wk->mapf_lsiz;
	z = sys.tp_y - wk->mapf_usiz;

	for(i = 0;i < PGMAP_TOWN_MAX;i++){
		tp = (TMAP_TOWN_PARAM*)&(TMapTownParam[i]);

	}
	return 0;
}

/**
 *	@brief	選んだ場所に既存のデータがあるかどうか？
 */
static int pgmapkey_IsMarkParamEnable(PGMAP_SYS_WORK* wk,u8 posid)
{
	MARKER_DATA_WK *mp;

	if(wk->cZone.mk_prm == NULL || posid >= 8){
		return FALSE;
	}
	mp = &(wk->cZone.mk_prm->mark);
	if(posid % 2 == 0){	//アイコンの有無
		if(mp->icon[posid/2] != MARKER_ICON_NULL){
			return TRUE;
		}
	}else{	//単語の有無
		if(mp->word[posid/2] != PMS_WORD_NULL){
			return TRUE;
		}
	}
	return FALSE;
}

/**
 *	@brief	ゴミ箱マークのOn/Off
 *
 *	@param	flag	TRUE:ON,FALSE:OFF
 */
static void pgmapkey_TrashMarkStateChange(PGMAP_SYS_WORK* wk,BOOL flag)
{
	wk->mkedit_view = flag;
	GF_BGL_ScrWriteExpand(wk->sys->bgl,GF_BGL_FRAME2_M,
		5,8,8,5,wk->pSMk0->rawData,14+(wk->mkedit_view*8),16,
		wk->pSMk0->screenWidth/8,wk->pSMk0->screenHeight/8);
	GF_BGL_LoadScreenV_Req(wk->sys->bgl,GF_BGL_FRAME2_M);
}

/**
 *	@brief	マークエディット画面、対象選択
 */
int PGMapKey_ContMEditTargetSelect(PGMAP_SYS_WORK* wk)
{
	u8 pos;

	if(sys.trg & PAD_BUTTON_B){
		Snd_SePlay(SE_PGEAR_CANCEL);
		//選択カーソルを消す
		CursorMvMan_SetCursorDrawFlag(wk->sys->curMan,CURMV_CURRENT,FALSE);
		return PGMAP_SEQ_MARK_END_MAP;
	}

	if(sys.trg & PAD_BUTTON_A){
		//現在の選択位置により分岐
		pos = CursorMvMan_GetPos(wk->sys->curMan);
		Snd_SePlay(SE_PGEAR_DECIDE);
		if(pos == 8){
			//選択カーソルを消す
			CursorMvMan_SetCursorDrawFlag(wk->sys->curMan,CURMV_CURRENT,FALSE);
			return PGMAP_SEQ_MARK_END_MAP;	//終了
		}
		if(pgmapkey_IsMarkParamEnable(wk,pos)){
			//削除モードに移行
			CursorMvMan_SetAnmFlagIdx(wk->sys->curMan,CURMV_CURRENT,FALSE);
			CursorMvMan_SetCurrent(wk->sys->curMan,PGKM_APP_PARAM3,0);
			CursorMvMan_SetCursorDrawFlag(wk->sys->curMan,CURMV_CURRENT,TRUE);

			pgmapkey_TrashMarkStateChange(wk,TRUE);
			//操作のステータスをセット
			wk->mkedit_st = MKEDIT_DEL;
			return -1;
		}else{
			if(pos % 2 == 0){
				//マーク選択モードに移行
				CursorMvMan_SetAnmFlagIdx(wk->sys->curMan,CURMV_CURRENT,FALSE);
				CursorMvMan_SetCurrent(wk->sys->curMan,PGKM_APP_PARAM2,0);
				CursorMvMan_SetCursorDrawFlag(wk->sys->curMan,CURMV_CURRENT,TRUE);
				//操作のステータスをセット
				wk->mkedit_st = MKEDIT_MSEL;
				return -1;
			}else{
				//簡易会話呼び出し
				wk->ret.word_pos = pos/2;	//選択場所コードを保存
				wk->ret.zone = wk->cZone.z_prm->zone_id;
				return PGMAP_SEQ_MARK_END_WORD;
			}
		}
	}

	if(sys.trg & PAD_KEY_LEFT){
		Snd_SePlay(SE_PGEAR_MOVE_CURSOR);
		CursorMvMan_MovePos(wk->sys->curMan,CURMV_DIR_LEFT);
	}else if(sys.trg & PAD_KEY_RIGHT){
		Snd_SePlay(SE_PGEAR_MOVE_CURSOR);
		CursorMvMan_MovePos(wk->sys->curMan,CURMV_DIR_RIGHT);
	}else if(sys.trg & PAD_KEY_UP){
		Snd_SePlay(SE_PGEAR_MOVE_CURSOR);
		CursorMvMan_MovePos(wk->sys->curMan,CURMV_DIR_UP);
	}else if(sys.trg & PAD_KEY_DOWN){
		Snd_SePlay(SE_PGEAR_MOVE_CURSOR);
		CursorMvMan_MovePos(wk->sys->curMan,CURMV_DIR_DOWN);
	}

	return -1;
}

/**
 *	@brief	ターゲット選択　タッチ
 */
int PGMapKey_ContMEditTSelectTouch(PGMAP_SYS_WORK* wk,BOOL* touch_f)
{
	int ret;
	u16	pat,idx;
	PGEAR_ACT_WORK* pAct = wk->pActWMan->pAct;

	static const RECT_HIT_TBL Target_TpRect[] = {
//		{0,191,0,255}, ty,by,lx,rx
		{TPMK_MARK_PY01,TPMK_MARK_PY01+TPMK_MARK_SY,TPMK_MARK_PX01,TPMK_MARK_PX01+TPMK_MARK_SX},
		{TPMK_PLATE_PY01,TPMK_PLATE_PY01+TPMK_PLATE_SY,TPMK_PLATE_PX01,TPMK_PLATE_PX01+TPMK_PLATE_SX},
		{TPMK_MARK_PY01,TPMK_MARK_PY01+TPMK_MARK_SY,TPMK_MARK_PX02,TPMK_MARK_PX02+TPMK_MARK_SX},
		{TPMK_PLATE_PY01,TPMK_PLATE_PY01+TPMK_PLATE_SY,TPMK_PLATE_PX02,TPMK_PLATE_PX02+TPMK_PLATE_SX},

		{TPMK_MARK_PY02,TPMK_MARK_PY02+TPMK_MARK_SY,TPMK_MARK_PX01,TPMK_MARK_PX01+TPMK_MARK_SX},
		{TPMK_PLATE_PY02,TPMK_PLATE_PY02+TPMK_PLATE_SY,TPMK_PLATE_PX01,TPMK_PLATE_PX01+TPMK_PLATE_SX},
		{TPMK_MARK_PY02,TPMK_MARK_PY02+TPMK_MARK_SY,TPMK_MARK_PX02,TPMK_MARK_PX02+TPMK_MARK_SX},
		{TPMK_PLATE_PY02,TPMK_PLATE_PY02+TPMK_PLATE_SY,TPMK_PLATE_PX02,TPMK_PLATE_PX02+TPMK_PLATE_SX},

		{TPMK_SMK_PY,TPMK_SMK_PY+TPMK_SMK_SY,TPMK_SMK_PX01,TPMK_SMK_PX01+TPMK_SMK_SX},
		{TPMK_SMK_PY,TPMK_SMK_PY+TPMK_SMK_SY,TPMK_SMK_PX02,TPMK_SMK_PX02+TPMK_SMK_SX},
		{TPMK_SMK_PY,TPMK_SMK_PY+TPMK_SMK_SY,TPMK_SMK_PX03,TPMK_SMK_PX03+TPMK_SMK_SX},
		{TPMK_SMK_PY,TPMK_SMK_PY+TPMK_SMK_SY,TPMK_SMK_PX04,TPMK_SMK_PX04+TPMK_SMK_SX},
		{TPMK_SMK_PY,TPMK_SMK_PY+TPMK_SMK_SY,TPMK_SMK_PX05,TPMK_SMK_PX05+TPMK_SMK_SX},
		{TPMK_SMK_PY,TPMK_SMK_PY+TPMK_SMK_SY,TPMK_SMK_PX06,TPMK_SMK_PX06+TPMK_SMK_SX},
		{TPMK_SMK_PY,TPMK_SMK_PY+TPMK_SMK_SY,TPMK_SMK_PX07,TPMK_SMK_PX07+TPMK_SMK_SX},
		{TPMK_SMK_PY,TPMK_SMK_PY+TPMK_SMK_SY,TPMK_SMK_PX08,TPMK_SMK_PX08+TPMK_SMK_SX},

		{TPMK_EXIT_PY,TPMK_EXIT_PY+TPMK_EXIT_SY,TPMK_EXIT_PX,TPMK_EXIT_PX+TPMK_EXIT_SX},
		{RECT_HIT_END,0,0,0}
	};

	static const RECT_HIT_TBL Mark_TpRect[] = {
//		{0,191,0,255}, ty,by,lx,rx
		{RECT_HIT_END,0,0,0}
	};

	if(GF_TP_GetCont() == 0){
		return PG_NEXT_NULL;
	}
	if(wk->input_st){
		return PG_NEXT_NULL;
	}

	ret = GF_TP_RectHitTrg(Target_TpRect);

	if(ret == RECT_HIT_NONE){
		return PG_NEXT_NULL;
	}

	*touch_f = TRUE;
	if(ret == 16){
		GF_BGL_ScrWriteExpand(wk->sys->bgl,GF_BGL_FRAME2_M,
			23,8,6,5,wk->pSMk0->rawData,7,16,
			wk->pSMk0->screenWidth/8,wk->pSMk0->screenHeight/8);
		GF_BGL_LoadScreenV_Req(wk->sys->bgl,GF_BGL_FRAME2_M);
		Snd_SePlay(SE_PGEAR_CANCEL);
		return PGMAP_SEQ_MARK_END_MAP;	//終了
	}
	if(ret >= 8){	//マークのドラッグ開始
		wk->touch_pos = ret-8;
		wk->mkedit_st = MKEDIT_MSEL;
		PGActWork_SPriSet(&pAct[EACT_MKDEF1+(ret-8)],MKACT_SPRI_1ST);
		Snd_SePlay(SE_PGEAR_SEAL_CATCH);
		return PG_NEXT_NULL;
	}
	//ターゲットの選択
	if(pgmapkey_IsMarkParamEnable(wk,ret)){	//既にデータがあるとき
		//削除モードに移行
		idx = ret/2;
		if(ret % 2 == 0){	//retをEACTのIDナンバー順に変換
			wk->touch_pos = idx;
			wk->tp_ofsx = wk->tp_ofsy = 0;
			PGActWork_SPriSet(&pAct[EACT_MARK1+idx],MKACT_SPRI_1ST);
		}else{
			wk->touch_pos = idx+4;
			wk->tp_ofsx = (EACT_PLATE_PX+(idx%2)*EACT_PLATE_SX)-sys.tp_x;
			wk->tp_ofsy = (EACT_PLATE_PY+(idx/2)*EACT_PLATE_SY)-sys.tp_y;
			PGActWork_SPriSet(&pAct[EACT_PLATE1+idx],MKACT_SPRI_1ST);
			FONTOAM_SetDrawPriority(wk->pFontOam[idx].foam,MKACT_SPRI_1ST-1);
		}
		wk->mkedit_st = MKEDIT_DEL;
		Snd_SePlay(SE_PGEAR_SEAL_CATCH);
		return PG_NEXT_NULL;
	}else if((ret % 2) == 1){	//データのないワードポジションをタッチした場合
		//簡易会話呼び出し
		wk->ret.word_pos = ret/2;	//選択場所コードを保存
		wk->ret.zone = wk->cZone.z_prm->zone_id;
		Snd_SePlay(SE_PGEAR_DECIDE);
		return PGMAP_SEQ_MARK_END_WORD;
	}
	return PG_NEXT_NULL;
}

/**
 *	@brief	ターゲットの削除＆マークの選択状態から、ターゲット選択状態に戻るときのカーソルセット
 */
static void pgmapkey_SetMEditTSelectReturn(PGMAP_SYS_WORK* wk)
{
	//選択カーソルは隠す
	CursorMvMan_SetPos(wk->sys->curMan,0);
	CursorMvMan_SetCursorDrawFlag(wk->sys->curMan,CURMV_CURRENT,FALSE);

	//カレントを変更
	CursorMvMan_SetCurrent(wk->sys->curMan,PGKM_APP_PARAM1,
		CursorMvMan_GetPosIdx(wk->sys->curMan,PGKM_APP_PARAM1));
	CursorMvMan_SetAnmFlagIdx(wk->sys->curMan,CURMV_CURRENT,TRUE);

	//操作のステータスをセット
	wk->mkedit_st = MKEDIT_SEL;
}

/**
 *	@brief	マークエディット画面、マーク選択
 */
int PGMapKey_ContMEditMarkSelect(PGMAP_SYS_WORK* wk)
{
	u8 pos,icon;

	if(sys.trg & PAD_BUTTON_A){
		Snd_SePlay(SE_PGEAR_DECIDE);
		//マークをセット
		icon = CursorMvMan_GetPos(wk->sys->curMan);
		pos = CursorMvMan_GetPosIdx(wk->sys->curMan,PGKM_APP_PARAM1);
		if(wk->cZone.mk_prm == NULL){
			wk->cZone.mk_prm = PGMapMk_EntryZoneData(wk,wk->cZone.z_prm->zone_id);
		}
		PGMapMk_AddIconParam(wk->cZone.mk_prm,pos/2,icon);

		//ガイド再描画
		PGMapSub_DrawEditGuide(wk,FALSE);
	}

	if(sys.trg & (PAD_BUTTON_B)){
		Snd_SePlay(SE_PGEAR_CANCEL);
		pgmapkey_SetMEditTSelectReturn(wk);
		return -1;
	}else if(GF_TP_GetTrg()){
		Snd_SePlay(SE_PGEAR_CANCEL);
		pgmapkey_SetMEditTSelectReturn(wk);

		if(wk->sys->key_mode != APP_KTST_TOUCH){
			PGMapSub_ToTouchChangeMark((void*)wk);
			wk->sys->key_mode = APP_KTST_TOUCH;
		}
		return -1;
	}
	if(sys.trg & PAD_KEY_LEFT){
		Snd_SePlay(SE_PGEAR_MOVE_CURSOR);
		CursorMvMan_MovePos(wk->sys->curMan,CURMV_DIR_LEFT);
	}else if(sys.trg & PAD_KEY_RIGHT){
		Snd_SePlay(SE_PGEAR_MOVE_CURSOR);
		CursorMvMan_MovePos(wk->sys->curMan,CURMV_DIR_RIGHT);
	}
	return -1;
}

/**
 *	@brief	マークのドラッグ＆セットモード　タッチ
 */
int PGMapKey_ContMEditMSelectTouch(PGMAP_SYS_WORK* wk)
{
	int ret;

	static const RECT_HIT_TBL Target_TpRect[] = {
//		{0,191,0,255}, ty,by,lx,rx
		{TPMK_MARK_PY01,TPMK_MARK_PY01+TPMK_MARK_SY,TPMK_MARK_PX01,TPMK_MARK_PX01+TPMK_MARK_SX},
		{TPMK_MARK_PY01,TPMK_MARK_PY01+TPMK_MARK_SY,TPMK_MARK_PX02,TPMK_MARK_PX02+TPMK_MARK_SX},
		{TPMK_MARK_PY02,TPMK_MARK_PY02+TPMK_MARK_SY,TPMK_MARK_PX01,TPMK_MARK_PX01+TPMK_MARK_SX},
		{TPMK_MARK_PY02,TPMK_MARK_PY02+TPMK_MARK_SY,TPMK_MARK_PX02,TPMK_MARK_PX02+TPMK_MARK_SX},
		{RECT_HIT_END,0,0,0}
	};

	if(GF_TP_GetCont() == 0){	//放された
		ret = GF_TP_HitSelf( Target_TpRect,sys.tp_x,sys.tp_y);
		Snd_SePlay(SE_PGEAR_SEAL_PUT);

		if(ret == RECT_HIT_NONE){
			PGActWork_PosSetUpdate(&(wk->pActWMan->pAct[EACT_MKDEF1+wk->touch_pos]),
				EACT_MKDEF_PX+(wk->touch_pos*EACT_MKDEF_SX),EACT_MKDEF_PY);
			PGActWork_SPriSet(&(wk->pActWMan->pAct[EACT_MKDEF1+wk->touch_pos]),MKACT_SPRI_DEF);
			wk->mkedit_st = MKEDIT_SEL;
			return PG_NEXT_NULL;
		}
		//マークセット
		if(wk->cZone.mk_prm == NULL){
			wk->cZone.mk_prm = PGMapMk_EntryZoneData(wk,wk->cZone.z_prm->zone_id);
		}
		PGMapMk_AddIconParam(wk->cZone.mk_prm,ret,wk->touch_pos);

		//ガイド再描画
		PGMapSub_DrawEditGuide(wk,FALSE);

		PGActWork_PosSetUpdate(&(wk->pActWMan->pAct[EACT_MKDEF1+wk->touch_pos]),
					EACT_MKDEF_PX+(wk->touch_pos*EACT_MKDEF_SX),EACT_MKDEF_PY);
		PGActWork_SPriSet(&(wk->pActWMan->pAct[EACT_MKDEF1+wk->touch_pos]),MKACT_SPRI_DEF);

		wk->mkedit_st = MKEDIT_SEL;
		return PG_NEXT_NULL;
	}
	PGActWork_PosSetUpdate(&(wk->pActWMan->pAct[EACT_MKDEF1+wk->touch_pos]),
				sys.tp_x,sys.tp_y);

	return -1;
}

/**
 *	@brief	指定のポジションデータを削除
 */
static void pgmapkey_TargetDelete(PGMAP_SYS_WORK* wk,u8 mode,u8 idx)
{
	u8 flag;

	if(mode == 0){	//アイコン
		flag = PGMapMk_DelIconParam(wk->cZone.mk_prm,idx);
	}else{	//単語
		flag = PGMapMk_DelWordParam(wk->cZone.mk_prm,idx);
	}
	if(flag == FALSE){
		//カレントゾーンから有効なマーカーパラメータはなくなった
		PGMapMk_DeleteZoneData(wk,wk->cZone.mk_prm);
		wk->cZone.mk_prm = NULL;
	}
	//ガイド再描画
	PGMapSub_DrawEditGuide(wk,FALSE);
}

/**
 *	@brief	マークエディット画面、削除シーケンス
 */
int PGMapKey_ContMEditTargetDelete(PGMAP_SYS_WORK* wk)
{
	u8 pos;

	if(sys.trg & PAD_BUTTON_A){
		//ターゲットデータを削除
		Snd_SePlay(SE_PGEAR_SEAL_DUST);
		pos = CursorMvMan_GetPosIdx(wk->sys->curMan,PGKM_APP_PARAM1);
		pgmapkey_TargetDelete(wk,pos%2,pos/2);
		pgmapkey_SetMEditTSelectReturn(wk);
		pgmapkey_TrashMarkStateChange(wk,FALSE);
	}
	if(sys.trg & (PAD_BUTTON_B)){
		Snd_SePlay(SE_PGEAR_CANCEL);
		pgmapkey_SetMEditTSelectReturn(wk);
		pgmapkey_TrashMarkStateChange(wk,FALSE);
	}else if(GF_TP_GetTrg()){
		Snd_SePlay(SE_PGEAR_CANCEL);
		pgmapkey_SetMEditTSelectReturn(wk);
		pgmapkey_TrashMarkStateChange(wk,FALSE);

		if(wk->sys->key_mode != APP_KTST_TOUCH){
			PGMapSub_ToTouchChangeMark((void*)wk);
			wk->sys->key_mode = APP_KTST_TOUCH;
		}
	}
	return -1;
}

/**
 *	@brief	ターゲット消去モード終了時に、オブジェをデフォルト位置に戻す
 */
static void pgmapkey_TDeleteObjPosReturn(PGMAP_SYS_WORK* wk,u8 pos)
{
	u8 idx;
	PGEAR_ACT_WORK* pAct = wk->pActWMan->pAct;

	if(pos < 4){	//マーク
		idx = wk->touch_pos;
		PGActWork_PosSetUpdate(&pAct[EACT_MARK1+idx],
			EACT_MARK_PX+(idx%2)*EACT_MARK_SX,EACT_MARK_PY+(idx/2)*EACT_MARK_SY);
		PGActWork_SPriSet(&pAct[EACT_MARK1+idx],MKACT_SPRI_DEF);
	}else{	//プレート
		idx = pos-4;
		PGActWork_PosSetUpdate(&pAct[EACT_PLATE1+idx],
			EACT_PLATE_PX+(idx%2)*EACT_PLATE_SX,EACT_PLATE_PY+(idx/2)*EACT_PLATE_SY);
		PGActWork_SPriSet(&pAct[EACT_PLATE1+idx],MKACT_SPRI_DEF);
		FONTOAM_SetMat(wk->pFontOam[idx].foam,FOAM_PLATE_OFSX, FOAM_PLATE_OFSY);
		FONTOAM_SetDrawPriority(wk->pFontOam[idx].foam,MKACT_SPRI_DEF-1);
	}
}

/**
 *	@brief	ターゲット消去モード　タッチ
 */
int PGMapKey_ContMEditTDeleteTouch(PGMAP_SYS_WORK* wk)
{
	int ret;
	u8	idx,flag;
	PGEAR_ACT_WORK* pAct = wk->pActWMan->pAct;

	static const RECT_HIT_TBL Target_TpRect[] = {
//		{0,191,0,255}, ty,by,lx,rx
		{TPMK_MARK_PY01,TPMK_MARK_PY01+TPMK_MARK_SY,TPMK_MARK_PX01,TPMK_MARK_PX01+TPMK_MARK_SX},
		{TPMK_MARK_PY01,TPMK_MARK_PY01+TPMK_MARK_SY,TPMK_MARK_PX02,TPMK_MARK_PX02+TPMK_MARK_SX},
		{TPMK_MARK_PY02,TPMK_MARK_PY02+TPMK_MARK_SY,TPMK_MARK_PX01,TPMK_MARK_PX01+TPMK_MARK_SX},
		{TPMK_MARK_PY02,TPMK_MARK_PY02+TPMK_MARK_SY,TPMK_MARK_PX02,TPMK_MARK_PX02+TPMK_MARK_SX},

		{TPMK_PLATE_PY01,TPMK_PLATE_PY01+TPMK_PLATE_SY,TPMK_PLATE_PX01,TPMK_PLATE_PX01+TPMK_PLATE_SX},
		{TPMK_PLATE_PY01,TPMK_PLATE_PY01+TPMK_PLATE_SY,TPMK_PLATE_PX02,TPMK_PLATE_PX02+TPMK_PLATE_SX},
		{TPMK_PLATE_PY02,TPMK_PLATE_PY02+TPMK_PLATE_SY,TPMK_PLATE_PX01,TPMK_PLATE_PX01+TPMK_PLATE_SX},
		{TPMK_PLATE_PY02,TPMK_PLATE_PY02+TPMK_PLATE_SY,TPMK_PLATE_PX02,TPMK_PLATE_PX02+TPMK_PLATE_SX},

		{TPMK_DEL_PY,TPMK_DEL_PY+TPMK_DEL_SY,TPMK_DEL_PX,TPMK_DEL_PX+TPMK_DEL_SX},
		{RECT_HIT_END,0,0,0},
	};

	if(GF_TP_GetCont() == 0){	//放された
		ret = GF_TP_HitSelf( Target_TpRect,sys.tp_x,sys.tp_y);

		if(ret == 8){	//データ削除
			pgmapkey_TargetDelete(wk,wk->touch_pos/4,wk->touch_pos%4);
			pgmapkey_TDeleteObjPosReturn(wk,wk->touch_pos);

			pgmapkey_TrashMarkStateChange(wk,FALSE);
			Snd_SePlay(SE_PGEAR_SEAL_DUST);
			wk->mkedit_st = MKEDIT_SEL;
			return PG_NEXT_NULL;
		}else if((ret == RECT_HIT_NONE) ||
				((wk->touch_pos/4) != (ret/4)) ||
				(wk->touch_pos == ret)){
			//なにもしないで元に戻す
			pgmapkey_TDeleteObjPosReturn(wk,wk->touch_pos);
			Snd_SePlay(SE_PGEAR_SEAL_PUT);
			wk->mkedit_st = MKEDIT_SEL;
			return PG_NEXT_NULL;
		}else if((ret/4) == 0){	//アイコン
			PGMapMk_SwapIconParam(wk->cZone.mk_prm,wk->touch_pos%4,ret%4);
		}else{
			PGMapMk_SwapWordParam(wk->cZone.mk_prm,wk->touch_pos%4,ret%4);
		}
		PGMapSub_DrawEditGuide(wk,FALSE);
		pgmapkey_TDeleteObjPosReturn(wk,wk->touch_pos);
		Snd_SePlay(SE_PGEAR_SEAL_PUT);
		wk->mkedit_st = MKEDIT_SEL;
		return PG_NEXT_NULL;
	}
	PGActWork_PosSetUpdate(&(wk->pActWMan->pAct[EACT_MARK1+wk->touch_pos]),
				sys.tp_x+wk->tp_ofsx,sys.tp_y+wk->tp_ofsy);
	if(wk->touch_pos >= 4){	//フォントも一緒に動かす
		FONTOAM_SetMat(wk->pFontOam[wk->touch_pos-4].foam,FOAM_PLATE_OFSX, FOAM_PLATE_OFSY);
	}

	if(GF_TP_SingleHitSelf(&(Target_TpRect[8]),sys.tp_x,sys.tp_y) != wk->mkedit_view){
		pgmapkey_TrashMarkStateChange(wk,wk->mkedit_view^1);
	}
	return PG_NEXT_NULL;
}